package com.fy.controller;

// Spring 相关

import cn.hutool.core.util.StrUtil;
import com.fy.common.annotation.GlobalInterceptor;
import com.fy.common.constants.MessageConstant;
import com.fy.ex.handler.ExceptionHandler;
import com.fy.service.AIService;
import com.fy.service.ChatConstantService;
import com.fy.utils.result.Result;
import io.reactivex.rxjava3.core.BackpressureStrategy;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import reactor.core.publisher.Flux;

import java.util.List;
import java.util.concurrent.CompletableFuture;

@Slf4j
@CrossOrigin
@RestController
@RequestMapping("/ai")
public class AIController {

  @Autowired
  private AIService aiService;

  @Autowired
  private ChatConstantService chatConstantService;

  /**
   * 获取随机问题列表
   * 从预设问答库中随机获取5个常见问题，用于展示和引导用户
   *
   * @return Result<List<String>> 随机问题列表
   */
  @ApiOperation(value = "获取随机问题列表", notes = "从预设问答库中随机获取5个常见问题，优先从缓存获取")
  @ApiResponses({
      @ApiResponse(code = 200, message = "获取成功"),
      @ApiResponse(code = 400, message = "请求错误"),
  })
  @GetMapping("/questions")
  @GlobalInterceptor(checkLogin = false)
  public Result<List<String>> getQuestions() {
    log.info("开始获取随机问题列表");
    return chatConstantService.getQuestions();
  }

  /**
   * 获取预设问答内容
   * 根据问题获取预设的回答内容，并更新访问计数
   *
   * @param question 预设问题内容
   * @return 预设的回答内容
   */
  @ApiOperation(value = "获取预设问答", notes = "根据问题获取系统预设的标准回答，并记录访问次数")
  @ApiResponses({
      @ApiResponse(code = 200, message = "获取成功"),
      @ApiResponse(code = 400, message = "请求错误"),
  })
  @GetMapping("/ChatConstant/{question}")
  public Result<String> chatConstant(
      @ApiParam(name = "question", value = "预设问题内容", required = true, example = "如何上传图片？") @PathVariable("question") String question) {
    log.info("开始处理预设问答请求, 问题: {}", question);

    // 参数校验
    ExceptionHandler.throwIf(StrUtil.isBlank(question),
        MessageConstant.PARAMS_ERROR);
    return chatConstantService.getAnswer(question);
  }

  /**
   * AI聊天流式响应接口
   * 基于SSE(Server-Sent Events)和RxJava实现的流式对话功能
   *
   * @param message 用户输入的消息
   * @return 基于SSE的消息流，实时返回AI的响应内容
   */
  @ApiOperation(value = "AI聊天流式对话", notes = "提供实时流式的AI对话功能，支持打字机效果的实时响应")
  @ApiResponses({
      @ApiResponse(code = 200, message = "成功建立流式连接"),
      @ApiResponse(code = 400, message = "请求错误")
  })
  @GetMapping(value = "/ChatStream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
  public Flux<ServerSentEvent<String>> streamChat(
      @ApiParam(name = "message", value = "用户输入的对话内容", required = true, example = "你好，请介绍一下你自己") @RequestParam String message) {
    log.info("开始处理AI流式对话请求, 用户输入: {}", message);

    ExceptionHandler.throwIf(StrUtil.isBlank(message),
        MessageConstant.PARAMS_ERROR);

    return Flux.from(
        aiService.streamChat(message)
            .toFlowable(BackpressureStrategy.BUFFER))
        .map(text -> ServerSentEvent.<String>builder()
            .data(text)
            .build())
        .doOnComplete(() -> log.info("AI流式对话响应完成")).doOnError(error -> log.error("AI流式对话发生错误: {}", error.getMessage()));
  }

  /**
   * 识别图片文字
   *
   * @param file
   * @return
   */
  @PostMapping("/ocr/extract-text")
  @GlobalInterceptor
  public Result<String> ocr(@RequestParam("file") MultipartFile file, String fileMd5) {
    return aiService.ocr(file, fileMd5);
  }

  @PostMapping("/document/word2pdf")
  public ResponseEntity<byte[]> wordToPdf(@RequestParam("file") MultipartFile file) {
    try {
      CompletableFuture<byte[]> future = aiService.wordToPdf(file);
      byte[] pdfContent = future.get(); // 等待异步结果

      HttpHeaders headers = new HttpHeaders();
      headers.setContentType(MediaType.APPLICATION_PDF);
      headers.setContentDispositionFormData("attachment", "converted.pdf");
      return ResponseEntity.ok().headers(headers).body(pdfContent);
    } catch (Exception e) {
      log.error("转换失败", e);
      return ResponseEntity.badRequest().build();
    }
  }

  @PostMapping("/document/word2html")
  public Result<String> wordToHtml(@RequestParam("file") MultipartFile file) {
    try {
      CompletableFuture<String> future = aiService.wordToHtml(file);
      String html = future.get(); // 等待异步结果
      return Result.success(html);
    } catch (Exception e) {
      log.error("转换失败", e);
      return Result.error("文档转换失败");
    }
  }

  @PostMapping("/audio/speech2text")
  public Result<String> speechToText(@RequestParam("file") MultipartFile file) {
    try {
      String text = aiService.speechToText(file).get();
      return Result.success(text);
    } catch (Exception e) {
      log.error("语音识别失败", e);
      return Result.error("语音识别失败");
    }
  }

  @PostMapping("/audio/convert")
  public ResponseEntity<byte[]> convertAudio(
      @RequestParam("file") MultipartFile file,
      @RequestParam("format") String format) {
    try {
      byte[] data = aiService.convertAudioFormat(file, format).get();
      HttpHeaders headers = new HttpHeaders();
      headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
      headers.setContentDispositionFormData("attachment", "converted." + format);
      return ResponseEntity.ok().headers(headers).body(data);
    } catch (Exception e) {
      log.error("音频转换失败", e);
      return ResponseEntity.badRequest().build();
    }
  }

  @PostMapping("/audio/duration")
  public Result<Long> getAudioDuration(@RequestParam("file") MultipartFile file) {
    try {
      Long duration = aiService.getAudioDuration(file).get();
      return Result.success(duration);
    } catch (Exception e) {
      log.error("获取音频时长失败", e);
      return Result.error("获取时长失败");
    }
  }

  @PostMapping("/image/compress")
  public ResponseEntity<byte[]> compressImage(
      @RequestParam("file") MultipartFile file,
      @RequestParam(value = "quality", defaultValue = "0.7") double quality) {
    try {
      byte[] data = aiService.compressImage(file, quality).get();
      HttpHeaders headers = new HttpHeaders();
      headers.setContentType(MediaType.IMAGE_JPEG);
      headers.setContentDispositionFormData("attachment", "compressed.jpg");
      return ResponseEntity.ok().headers(headers).body(data);
    } catch (Exception e) {
      log.error("图片压缩失败", e);
      return ResponseEntity.badRequest().build();
    }
  }

  // @PostMapping("/image/watermark")
  // public ResponseEntity<byte[]> addWatermark(
  // @RequestParam("file") MultipartFile file,
  // @RequestParam("text") String text,
  // @RequestParam(value = "gravity", defaultValue = "southeast") String gravity,
  // @RequestParam(value = "dissolve", defaultValue = "90") Integer dissolve,
  // @RequestParam(value = "dx", defaultValue = "10") Integer dx,
  // @RequestParam(value = "dy", defaultValue = "10") Integer dy) {
  // try {
  // byte[] data = aiService.addWatermark(file, text, gravity, dissolve, dx,
  // dy).get();
  // HttpHeaders headers = new HttpHeaders();
  // headers.setContentType(MediaType.IMAGE_JPEG);
  // headers.setContentDispositionFormData("attachment", "watermarked.jpg");
  // return ResponseEntity.ok().headers(headers).body(data);
  // } catch (Exception e) {
  // log.error("添加水印失败", e);
  // return ResponseEntity.badRequest().build();
  // }
  // }

}